/***************************************************************************
 *   oboe.math.Frame							   *
 *   Copyright (C) 2011 by Felipe Manga					*
 *   lufeboma@gmail.com							*
 *									 *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the	   *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to	*
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:						 *
 *									 *
 *   The above copyright notice and this permission notice shall be	*
 *   included in all copies or substantial portions of the Software.	   *
 *									 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,	   *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF	*
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR	 *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.					   *
 ***************************************************************************/

package oboe.math;

import flash.display.Graphics;
import flash.display.TriangleCulling;
import flash.utils.Dictionary;

import oboe.core.Oboe;
import oboe.core.RenderSettings;
import oboe.math.*;
import oboe.math.Triangle3D;

import flash.Vector;

class Frame
{
private var index:Vector<Int>;
private var verts:Vector<Float>;
private var uvs:Vector<Float>;

private static var frameCount:Int = 0;

public static function getFrameCount():Int
{
	return frameCount;
}

public function new( tris:Array, verts:Vector<Float>, uvs:Vector<Float> )
{
	if( !tris ) return;
	var index:Vector<Int> = this.index = new Vector<Int>( tris.length*3, true );
	this.verts = verts;
	this.uvs = uvs;

	tris.sortOn("z", Array.NUMERIC);
//		tris.sort( 
//		function( a:Triangle3D, b:Triangle3D ):Float
//		{
//			return b.z - a.z;
//		}
//		);
	
	var l:Int=tris.length;
	var c:Int=tris.length*3-1;
	var u:Int=0;
	for each(var tri:Triangle3D in tris )// ( var t:Int=0; t<l; ++t )
	{
	index[c--] = tri.pointA;
	index[c--] = tri.pointB;
	index[c--] = tri.pointC;
	}
}

//	private function prepareQDMesh( tris:Vector<Triangle3D> ):Void
//	{
//		this.verts = new Vector<Float>( tris.length*6, true );
//		this.uvs = new Vector<Float>( tris.length*6, true );
//		this.index = null;
//		
//		var v:Int=0;
//		var u:Int=0;
//		for( var i:Int=0; i<tris.length; i++ )
//		{
//		var t:Triangle3D = tris[i];
//		
//		this.verts[v++] = t.pointAx; this.verts[v++] = t.pointAy;
//		this.verts[v++] = t.pointBx; this.verts[v++] = t.pointBy;
//		this.verts[v++] = t.pointCx; this.verts[v++] = t.pointCy;
//		
//		this.uvs[u++] = t.uvA.x; this.uvs[u++] = t.uvA.y;
//		this.uvs[u++] = t.uvB.x; this.uvs[u++] = t.uvB.y;
//		this.uvs[u++] = t.uvC.x; this.uvs[u++] = t.uvC.y;
//		}
//	}

//	private function prepareIndexedMesh( tris:Vector<Triangle3D> ):Void
//	{
//		this.verts = new Vector();
//		this.uvs = new Vector();
//		this.index = new Vector();
//		
//		++frameCount;
//		if( Oboe.flags["DEBUG_3D_CACHE"] )
//		{
//		trace( "Creating frame ", frameCount );		
//		}
//		
//		var tmp:Object = {};
//		var pos:Int=0;
//		var p:Int;
//		var vertex:Float3D;
//		var uv:Float2D;
//		for( var i:Int=0; i<tris.length; i++ )
//		{
//		var t:Triangle3D = tris[i];
////		this.addPoint( tmp, t.pointA, t.uvA );
////		this.addPoint( tmp, t.pointB, t.uvB );
////		this.addPoint( tmp, t.pointC, t.uvC );
//
//		var k:String;
//		
//		vertex = t.pointA; uv=t.uvA;
//		k=int(vertex.x*10)+":"+int(vertex.y*10)+":"+uv.x+":"+uv.y;
//		p=tmp[k];
//		if( !p )
//		{
//			this.verts.push( vertex.x, vertex.y );
//			this.uvs.push( uv.x, uv.y );
//			pos++;
//			tmp[k] = pos;
//			p = pos;
//		}
//		this.index.push( p-1 );
//
//		vertex = t.pointB; uv=t.uvB;
//		k=int(vertex.x*10)+":"+int(vertex.y*10)+":"+uv.x+":"+uv.y;
//		p=tmp[k];
//		if( !p )
//		{
//			this.verts.push( vertex.x, vertex.y );
//			this.uvs.push( uv.x, uv.y );
//			pos++;
//			tmp[k] = pos;
//			p = pos;
//		}
//		this.index.push( p-1 );
//		
//		vertex = t.pointC; uv=t.uvC;
//		k=int(vertex.x*10)+":"+int(vertex.y*10)+":"+uv.x+":"+uv.y;
//		p=tmp[k];
//		if( !p )
//		{
//			this.verts.push( vertex.x, vertex.y );
//			this.uvs.push( uv.x, uv.y );
//			pos++;
//			tmp[k] = pos;
//			p = pos;
//		}
//		this.index.push( p-1 );
//		}
//	}
//	
//	private function addPoint( tmp:Object, vertex:Float3D, uv:Float2D ):Void
//	{
//		var x:Float = vertex.x;
//		var y:Float = vertex.y;
//		var k:String = x+":"+y+":"+uv.x+":"+uv.y;
//		var pos:Int = this.verts.length/2;
//		
//		if( !tmp.hasOwnProperty(k) )
//		{
//		tmp[k] = pos;
//		this.verts.push( x, y );
//		this.uvs.push( uv.x, uv.y );
//		}
//		else
//		{
//		pos = tmp[k]; 
//		}
//		
//		this.index.push( pos );
//	}
//	
public function draw( s:RenderSettings ):Void
{
	if( s.texture )
	{
	s.target.beginBitmapFill( s.texture );
	s.target.drawTriangles(
		this.verts,
		this.index,
		this.uvs,
		RenderSettings.CULL_NONE // s.culling
	);
	s.target.endFill();
	}
	else
	{
	s.target.beginFill( s.color );
	s.target.drawTriangles(
		this.verts,
		this.index,
		null,
		RenderSettings.CULL_NONE // s.culling
	);
	s.target.endFill();
	}
}
}